<!DOCTYPE html>
<meta charset="utf-8">
<title>Force-Directed Graph</title>
<style>

    .link {
        fill: none;
        stroke: #666;
        stroke-width: 1.5px;
    }

    #licensing {
        fill: green;
    }

    .link.licensing {
        stroke: green;
    }

    .link.resolved {
        stroke-dasharray: 0, 2;
    }

    circle {
        fill: #ccc;
        stroke: #333;
        stroke-width: 1.5px;
    }

    text {
        font: 12px Microsoft YaHei;
        pointer-events: none;
        text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff;
    }

    .linetext {
        font-size: 12px;
    }
</style>
<body style="overflow-x: hidden ;overflow-y: hidden">
<script src="VIS/dist/d3.v3.min.js"></script>
<script>


    var jsonHtml =
        {
            'name': '知识图谱',
            'children': [{
                'name': '关键词',
                'children': [{'name': '中国'}, {'name': '贸易'}, {
                    'name': '美国',
                    'children': []
                }, {'name': '政策'}, {'name': '经济'}, {
                    'name': '戴琪',
                    'children': []
                }, {'name': '市场经济'}, {'name': '做法'}, {
                    'name': '对华贸易'
                }, {'name': '政府'}]
            }, {
                'name': '高频词',
                'children': [{'name': '中国'}, {'name': '贸易'}, {
                    'name': '美国',
                    'children': []
                }, {'name': '政策'}, {'name': '经济'}, {
                    'name': '戴琪',
                    'children': []
                }, {'name': '做法'}, {'name': '对华贸易'}, {
                    'name': '表示',
                    'children': []
                }, {'name': '基础', 'children': []}]
            }, {'name': '人物', 'children': [{'name': '戴琪'}]}, {
                'name': '组织机构'
            }, {'name': '地名', 'children': [{'name': '中国'}, {'name': '美国'}]}]
        }
    var width = 1560,
        height = 800,
        root;
    var force = d3.layout.force()
        .size([width, height])//作用域的大小
        .linkDistance(100)//连接线长度
        .charge(-400)//顶点的电荷数。该参数决定是排斥还是吸引，数值越小越互相排斥
        .on("tick", tick)//指时间间隔，隔一段时间刷新一次画面
        .start();//开始转换

    var zoom = d3.behavior.zoom()//缩放配置，
        .scaleExtent([0.4, 2])//缩放比例
        .on("zoom", zoomed);

    function zoomed() {//缩放函数

        svg.selectAll("g").attr("transform",//svg下移动大小
            "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
        /*console.log(d3.event.translate+"/"+d3.event.scale);*/
    }

    var svg = d3.select("body").append("svg")
        .attr("preserveAspectRatio", "none")
        .attr("viewBox", "0 0 1920 1000")
        .call(zoom)
    ;
    var link = svg.selectAll(".link"),
        node = svg.selectAll(".node");
    var svg_text = svg.selectAll('text');
    // var svg_marker = svg.selectAll('marker');
    // console.log(svg_marker)

    root = jsonHtml;
    update();


    //status update
    function update() {
        var nodes = flatten(root),
            links = d3.layout.tree().links(nodes);

        // Restart the force layout.
        force
            .nodes(nodes)
            .links(links)
            .start();
        // Update the links…
        link = link.data(links, function (d) {
            return d.target.id;
        });

        // Exit any old links.
        link.exit().remove();

        // Enter any new links.
        link.enter()
            // .append("g")
            .insert("line", ".node")
            .attr("class", "link")
            .attr("x1", function (d) {
                return d.source.x;
            })
            .attr("y1", function (d) {
                return d.source.y;
            })
            .attr("x2", function (d) {
                return d.target.x;
            })
            .attr("y2", function (d) {
                return d.target.y;
            })
        ;

        // 更新节点…
        node = node.data(nodes, function (d) {
            return d.id;
        }).style("fill", color);

        // 退出任何旧节点.
        node.exit().remove();

        // 输入任何新节点.
        node.enter()
            .append("circle")
            // .append("g")
            .attr("class", "node")
            .attr("cx", function (d) {
                return d.x;
            })
            .attr("cy", function (d) {
                return d.y;
            })
            .attr("r", function (d) {
                return Math.sqrt(d.size) / 10 || 4.5;
            })
            .style("fill", color)
            .on("dblclick", click)
            // .on("click", oneclick)
            .call(force.drag)
            // 20211104 调整圆圈半径
            .attr("r", 20)//设置圆圈半径
        ;
        svg_text = svg_text.data(nodes, function (d) {
            return d.name;
        })
        svg_text.exit().remove();


        // text
        svg_text.enter()
            .append('text')
            .style('fill', '#000')
            // .append("g")
            .attr('dominant-baseline', 'middle')
            .attr('text-anchor', 'middle')
            .text(function (d) {
                return d.name
            });
        svg_text
            .attr('x', function (d) {
                return d.x
            })
            .attr('y', function (d) {
                return d.y
            })
            .attr('dominant-baseline', 'middle')
            .attr('text-anchor', 'middle')
            .text(function (d) {
                return d.name
            });

        // svg_text
        //
        //     .attr('x', function (d) {
        //         return d.x
        //     })
        //     .attr('y', function (d) {
        //         return d.y
        //     })
        // ;
    }

    function tick() {
        link.attr("x1", function (d) {
            return d.source.x;
        })
            .attr("y1", function (d) {
                return d.source.y;
            })
            .attr("x2", function (d) {
                return d.target.x;
            })
            .attr("y2", function (d) {
                return d.target.y;
            });

        node.attr("cx", function (d) {
            return d.x;
        })
            .attr("cy", function (d) {
                return d.y;
            });
        svg_text
            .attr('x', function (d) {
                return d.x
            })
            .attr('y', function (d) {
                return d.y
            });
    }

    // Color leaf nodes orange, and packages white or blue.
    function color(d) {
        return d._children ? "#3182bd" : d.children ? "#c6dbef" : "#fd8d3c";
    }

    // Toggle children on click.
    function click(d) {
        if (!d3.event.defaultPrevented) {
            if (d.children) {
                d._children = d.children;
                d.children = null;
            } else {
                d.children = d._children;
                d._children = null;
            }
            update();
        }
    }

    function oneclick(d) {
        console.log(d)
    }

    // Returns a list of all nodes under the root.
    function flatten(root) {
        var nodes = [], i = 0;

        function recurse(node) {
            if (node.children) node.children.forEach(recurse);
            if (!node.id) node.id = ++i;
            nodes.push(node);
        }

        recurse(root);
        return nodes;
    }

</script>